/*
 * Copyright (c) 2024 Black Sesame Technologies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <thread>

#include "dal_msg/dalidl_runtime_c/message_type_support_struct.h"
#include "dalidl_typesupport_introspection_cpp/identifier.hpp"
#include "serdata.hpp"
#include "TypeSupport2.hpp"

#include "dds/dds.h"

#include "mj_interfaces/msg/mjtype.hpp"
#include "cyclonedds_pubsub.hpp"

mj_interfaces::msg::Mjtype mjtype;

int main(int argc, char** argv)
{
    dds_entity_t participant = dds_create_participant(20, NULL, NULL);
    if (participant < 0) {
        std::cout << "create participant failed";
        return 1;
    }

    const dalidl_message_type_support_t& type_supports =
        get_message_type_support_handle<mj_interfaces::msg::Mjtype>();
    const dalidl_message_type_support_t* type_support = get_message_typesupport_handle(
        &type_supports, dalidl_typesupport_introspection_cpp::typesupport_identifier);

    if (!type_support) {
        std::cout << "type_support is null";
        return 1;
    }

    bool is_fixed_type = is_type_self_contained(type_support);
    uint32_t sample_size =
        static_cast<uint32_t>(dal_cyclonedds_cpp::get_message_size(type_support));
    auto sertype = create_sertype(
        type_support->typesupport_identifier,
        create_message_type_support(type_support->data, type_support->typesupport_identifier),
        false,
        dal_cyclonedds_cpp::make_message_value_type(&type_supports),
        sample_size,
        is_fixed_type);

    ddsi_sertype* p = (ddsi_sertype*)sertype;
    dds_entity_t topic =
        dds_create_topic_sertype(participant, "HelloWorldTopic", &p, nullptr, nullptr, nullptr);
    if (topic < 0) {
        std::cout << "create topic failed";
        ddsi_sertype_unref(sertype);
        return 1;
    }

    dds_entity_t publisher = dds_create_publisher(participant, NULL, NULL);
    if (publisher < 0) {
        std::cout << "create publisher failed";
        return 1;
    }

    dds_qos_t* qos = dds_create_qos();
    dds_qset_history(qos, DDS_HISTORY_KEEP_ALL, DDS_LENGTH_UNLIMITED);

    dds_history_kind_t hk;
    int32_t hd;
    dds_qget_history(qos, &hk, &hd);
    dds_qset_durability(qos, DDS_DURABILITY_TRANSIENT_LOCAL);
    dds_qset_durability_service(
        qos, DDS_SECS(0), hk, hd, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED, DDS_LENGTH_UNLIMITED);

    dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_INFINITY);

    dds_entity_t datawriter = dds_create_writer(publisher, topic, qos, NULL);
    if (datawriter < 0) {
        std::cout << "create datawriter failed";
        return 1;
    }

    mj_interfaces::msg::Mjtype mj_type;
    mj_type.str = "mjtype";
    while (1) {
        mj_type.i8 += 1;
        mj_type.i16 += 1;
        dds_write(datawriter, &mj_type);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    return 0;
}